#include "BinaryTree.h"
#include "Global.h"

BinaryTree::BinaryTree(void){
	root = new BinaryNode();
	count = 0;
	
}

BinaryTree::BinaryTree(int _mapwidth, int _mapheight){
	mapwidth = _mapwidth;
	mapheight = _mapheight;	
	root = new BinaryNode(0, 0, mapwidth, mapheight, "");
	count = 0;
}

BinaryTree::~BinaryTree(void){}

void BinaryTree::Release(){
	Release(root);
}

void BinaryTree::Release(BinaryNode *root){

	if(root->LNode != NULL)
		Release(root->LNode);
	if(root->RNode != NULL)
		Release(root->RNode);
	root->Release();
	delete root;
}
void BinaryTree::Reset(){

	Release(root);
	root = new BinaryNode();
	count = 0;
}

void BinaryTree::ReadBinaryTreeFormFile(int level)
{
	char filePath[50];
	sprintf_s(filePath,"map\\%dBinaryTree.txt",level);

	string str;
	ifstream file;

	file.open(filePath);
	
	if(!file.is_open()){
		trace(L"Khong doc duoc file BinaryTree cua Map%d", level);
		exit(EXIT_FAILURE);
	}

	while(getline(file, str))
	{
		istringstream ss(str);

		string id;
		string bNode;
		ss >> id;
		while(ss.good())
		{
			string text;
			ss >> text;
			bNode += text + " ";
		}
		
		bNode.erase(0, bNode.find_first_not_of(' '));
		bNode.erase(bNode.find_last_not_of(' ')+1);    
		bTreeMap[id] = bNode;

	}
}
void BinaryTree::Deserialize()
{
	SaveNode(root);
}

void BinaryTree::SaveNode(BinaryNode *iroot){
	string id_L = iroot->id + "0";
	string id_R =  iroot->id + "1";
	for (map<string, string>::iterator ii = bTreeMap.begin(); ii != bTreeMap.end(); ++ii)
	{
		
		if (id_L.compare(ii->first) == 0)
		{

			GetNodeInfo(ii->second);	
			iroot->LNode = new BinaryNode(rNode.left, rNode.top, rNode.right, rNode.bottom, id_L);
			iroot->LNode->GetListObj(list_id,rNode.left,rNode.right);
			list_id = "";
			SaveNode(iroot->LNode);
		}
		if (id_R.compare(ii->first) == 0)
		{
			GetNodeInfo(ii->second);
			iroot->RNode = new BinaryNode(rNode.left, rNode.top, rNode.right, rNode.bottom, id_R);
			iroot->RNode->GetListObj(list_id,rNode.left,rNode.right);
			list_id = "";
			SaveNode(iroot->RNode);
		}
	}
}

void BinaryTree::GetNodeInfo(string info){
	
	istringstream ss(info);
	int left,top,right,bottom;
	ss >> left >> top >> right >> bottom; 
	rNode.left = left;
	rNode.top = top;
	rNode.right = right;
	rNode.bottom = bottom;
	while(ss.good()){
		string temp;
		ss >> temp;
		list_id += temp + " ";
	}

	list_id.erase(0, list_id.find_first_not_of(' '));
	list_id.erase(list_id.find_last_not_of(' ')+1);
	ss.str().clear();
}
void BinaryTree::RemoveObj(Static* obj){
	RemoveObj(root, obj);	
}

void BinaryTree::RemoveObj(BinaryNode* root, Static* obj){

	root->listObject.remove(obj);

	if (root->LNode != NULL)
		RemoveObj(root->LNode, obj);	
	if (root->RNode != NULL)
		RemoveObj(root->RNode, obj);

	Global::listStaticObj.remove(obj);
}
void BinaryTree::RenderScreen(){
	RenderScreen(root);
	
}
void BinaryTree::RenderScreen(BinaryNode *root){
	root->Render();

	if ((root->LNode != NULL) && (Global::CheckRectInRect(Global::Screen, root->LNode->rect)))		
		RenderScreen(root->LNode);
	if ((root->RNode != NULL) && (Global::CheckRectInRect(Global::Screen, root->RNode->rect)))
		RenderScreen(root->RNode);
	
}

void BinaryTree::UpdateScreen()
{
	Global::listStaticObjRender.clear();
	UpdateScreen(root);
}

void BinaryTree::UpdateScreen( BinaryNode* root )
{
	root->Update();

	if ((root->LNode != NULL) && (Global::CheckRectInRect(Global::Screen, root->LNode->rect)))
	{
		UpdateScreen(root->LNode);
	}
	if ((root->RNode != NULL) && (Global::CheckRectInRect(Global::Screen, root->RNode->rect)))
	{
		UpdateScreen(root->RNode);
	}

}